package cn.gx.learn.security_boot_jwt_websocket.base.service.user;

import cn.gx.learn.security_boot_jwt_websocket.springsecurity.JWT.JWTUtils;
import cn.gx.learn.security_boot_jwt_websocket.base.dal.database.User;
import cn.gx.learn.security_boot_jwt_websocket.base.dal.mysql.UserMapper;
import cn.gx.learn.security_boot_jwt_websocket.springsecurity.dal.UserDetail;
import com.nimbusds.jose.JOSEException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private UserMapper userMapper;

    public String uerLogin(String username,String password) throws JOSEException {
        UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(username,password);
        Authentication authentication=authenticationManager.authenticate(authenticationToken);
        if(!authentication.isAuthenticated()){
            throw new JOSEException("Invalid username or password");
        }
        UserDetail userDetail=(UserDetail)authentication.getPrincipal();
        String token= JWTUtils.getToken(userDetail.getUser());
        return token;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)//通过注解回滚，能做到避免主键冲突，但被动防御，会有每次冲突都要回滚，数据库需要撤销操作，增加系统开销的问题，作为兜底
    public String userRegister(User user) throws JOSEException {
        User user1=userMapper.selectByName(user.getUsername());
        if(user1!=null){
            return "用户已存在";
        }else {
        String encode = passwordEncoder.encode(user.getPassword());
        user.setPassword(encode);
        userMapper.insert(user);
        return "success";
        }
    }
}
